package com.hyt.it.ogt.kq.service.gov.service.impl;

import com.alibaba.fastjson.JSON;
import com.hyt.it.ogt.kq.common.config.exception.KqException;
import com.hyt.it.ogt.kq.common.enums.ProgressEnum;
import com.hyt.it.ogt.kq.service.gov.model.vo.ProgressVO;
import com.hyt.it.ogt.kq.service.gov.service.IProgressService;
import com.hyt.loginfo.service.IBaseLoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.websocket.Session;
import java.text.NumberFormat;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static com.hyt.it.ogt.kq.common.gov.enums.CacheKeyEnum.*;

@Slf4j
@Service
public class ProgressServiceImpl implements IProgressService {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private IBaseLoginService iBaseLoginService;

    @Override
    public void getProgressForWebsocket(Session session, String taskId, int progressType) throws Exception {
        String content = JSON.toJSONString(this.get(taskId, progressType));
        session.getBasicRemote().sendText(content);
        TimeUnit.SECONDS.sleep(1);
    }

    @Override
    public ProgressVO get(String taskId, int progressType) {
        ProgressVO progressVO = new ProgressVO();
        try {
            // 进度条完成数量
            String progressKey = null;
            // 进度条完成数量
            String totalKey = null;
            String lockErrKey = null;
            switch (ProgressEnum.getByCode(progressType)) {
                case CREATE_ADMISSION_TICKET:
                    //生成全部准考证
                    progressKey = CREATE_ADMISSION_TICKET_PROGRESS_KEY.getCacheEnumKey(taskId);
                    totalKey = CREATE_ADMISSION_TICKET_PROGRESS_TOTAL_KEY.getCacheEnumKey(taskId);
                    break;
                case DATA_LOCK:
                    //锁定编排数据
                    progressKey = DATA_LOCK_PROGRESS_KEY.getCacheEnumKey(taskId);
                    totalKey = DATA_LOCK_TOTAL_KEY.getCacheEnumKey(taskId);
                    lockErrKey = DATA_LOCK_ERROR_KEY.getCacheEnumKey(taskId);
                    break;
                case EXPORT_ADMISSION_TICKET:
                    //导出准考证
                    String userId = iBaseLoginService.getUserId();
                    progressKey = EXPORT_ADMISSION_TICKET_PROGRESS_KEY.getCacheEnumKey(taskId, userId);
                    totalKey = EXPORT_ADMISSION_TICKET_PROGRESS_TOTAL_KEY.getCacheEnumKey(taskId, userId);
                    break;
                case CREATE_ROOM_DATA:
                    //生成考务包
                    progressKey = CREATE_ROOM_DATA_PROGRESS_KEY.getCacheEnumKey(taskId);
                    totalKey = CREATE_ROOM_DATA_PROGRESS_TOTAL_KEY.getCacheEnumKey(taskId);
                    break;
                case CREATE_MOCK_ROOM_DATA:
                    //生成模拟测试考务包
                    progressKey = CREATE_MOCK_ROOM_DATA_PROGRESS_KEY.getCacheEnumKey(taskId);
                    totalKey = CREATE_MOCK_ROOM_DATA_PROGRESS_TOTAL_KEY.getCacheEnumKey(taskId);
                    break;
                case KW_BINDING_BM_DATA:
                    //锁定编排数据
                    progressKey = GOV_BING_BM_PROCESS_CACHE_KEY.getCacheEnumKey(taskId); //CacheKeyManager.getBingingLockProgressKey(taskId);
                    totalKey = GOV_BING_BM_TOTAL_CACHE_KEY.getCacheEnumKey(taskId); //CacheKeyManager.getKwBingingDataLockTotalKey(taskId);
                    lockErrKey = GOV_BING_BM_ERROR_CACHE_KEY.getCacheEnumKey(taskId); //CacheKeyManager.getKwBingingDataLockErrKey(taskId);
                    break;
                default:
                    break;
            }
            // 完成数量
            Object err = null;
            Optional<String> optional = Optional.ofNullable(lockErrKey);
            if (optional.isPresent()) {
                err = redisTemplate.opsForValue().get(optional.get());
            }
            if (err != null) {
                int code = Integer.valueOf(err.toString());
                throw new KqException(code, "异常");
            } else {
                // 完成数量
                Object progress = null;
                if(StringUtils.isNotEmpty(progressKey)) {
                    // 完成数量
                    progress = redisTemplate.opsForValue().get(progressKey);
                }
                // 总数
                Object total = null;
                if(StringUtils.isNotEmpty(totalKey)) {
                    // 总数
                    total = redisTemplate.opsForValue().get(totalKey);
                }
                log.debug(" 获取进度：{}#{}", progress, total);
                if (progress == null && total == null) {
                    log.info("获取进度为空：{}#{}", taskId, progressType);
                    TimeUnit.SECONDS.sleep(2);
                } else {
                    // 其中一个为null
                    if (progress == null || total == null) {
                        progressVO.setCode(0);
                        progressVO.setPercentage(0);
                    } else {
                        NumberFormat format = NumberFormat.getInstance();
                        format.setMaximumFractionDigits(2);
                        String resultStr = format.format(Double.valueOf(progress.toString()) /
                                Double.valueOf(total.toString()) * 100);
                        int percentage = (int) NumberUtils.toFloat(resultStr);
                        if (percentage >= 100) {
                            progressVO.setCode(1);
                            progressVO.setPercentage(100);
                        } else {
                            progressVO.setPercentage(percentage);
                            progressVO.setCode(0);
                        }
                    }
                }
            }
		} catch (KqException e) {
			throw e;
		} catch (InterruptedException e) {
			progressVO.setCode(2);
			log.error("获取进度异常：", e);
			Thread.currentThread().interrupt();
		} catch (Exception e) {
			progressVO.setCode(2);
			log.error("获取进度异常：", e);
		}
		return progressVO;
    }
}
